package com.gecba.system.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import com.gecba.modular.jpa.service.impl.ServiceImpl;
import com.gecba.modular.jpa.utils.StringUtils;
import com.gecba.system.dao.repository.SysUserRepository;
import com.gecba.system.dao.repository.SysUserRoleRepository;
import com.gecba.system.entity.SysUser;
import com.gecba.system.entity.SysUserRole;
import com.gecba.system.service.SpecificationImpl;
import com.gecba.system.service.SysUserService;
import com.gecba.system.vo.SearchVO;
import com.github.xiaoymin.knife4j.core.util.StrUtil;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.beanutils.PropertyUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Example;
import org.springframework.data.domain.ExampleMatcher;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.lang.Nullable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.persistence.criteria.*;
import java.beans.PropertyDescriptor;
import java.lang.reflect.InvocationTargetException;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 *
 *@author ChenBo
 *@date 2021/7/19
 */
@Service
@Slf4j
public class SysUserServiceImpl extends ServiceImpl<SysUserRepository,SysUser,Long> implements SysUserService {

    @Autowired
    private SysUserRepository sysUserRepository;

    @Autowired
    private SysUserRoleRepository sysUserRoleRepository;


    /**
     * 多条件分页获取用户列表
     *
     * @param sysUser
     * @param searchVO
     * @param initPage
     * @author ChenBo
     * @date 2021/7/19
     */
    @Override
    public Page<SysUser> findByCondition(SysUser sysUser, SearchVO searchVO, Pageable initPage) {

        Page<SysUser> userPages = sysUserRepository.findAll(SpecificationImpl.specification(sysUser), initPage);

        List<SysUser> content = userPages.getContent();
        List<Long> userIdList = content.stream().filter(Objects::nonNull).map(SysUser::getId).collect(Collectors.toList());
        List<SysUserRole> userRoleList = sysUserRoleRepository.findAllByUserIdIn(userIdList);
        Map<Long, List<SysUserRole>> userRoleMap = userRoleList.stream().filter(Objects::nonNull).collect(Collectors.groupingBy(SysUserRole::getUserId));
        if(CollectionUtil.isNotEmpty(userRoleMap)){
            userPages.forEach(user->{
                List<SysUserRole> userRoles = userRoleMap.get(user.getId());
                List<Long> collect = userRoles.stream().filter(Objects::nonNull).map(SysUserRole::getRoleId).collect(Collectors.toList());
                String roles = CollectionUtil.join(collect, ",");
                user.setRoles(roles);
            });
        }
        return userPages;
    }





    /**
     * 添加用户
     *
     * @param sysUser
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    @SneakyThrows(Exception.class)
    public SysUser addUser(SysUser sysUser) {
        save(sysUser);
        String roles = sysUser.getRoles();
        if(StringUtils.isNotBlank(roles)){
            List<SysUserRole> userRoleList = Arrays.stream(roles.split(",")).filter(StringUtils::isNotBlank)
                    .map(roleId -> {
                        SysUserRole sysUserRole = new SysUserRole();
                        sysUserRole.setUserId(sysUser.getId());
                        sysUserRole.setRoleId(Long.valueOf(roleId));
                        return sysUserRole;
                    }).collect(Collectors.toList());
            sysUserRoleRepository.saveAll(userRoleList);
        }
        return sysUser;
    }

    /**
     * 更新用户
     *
     * @param sysUser
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    @SneakyThrows(Exception.class)
    public SysUser updateUser(SysUser sysUser) {
        saveOrUpdate(sysUser);
        String roles = sysUser.getRoles();
        if(StringUtils.isNotBlank(roles)){
            sysUserRoleRepository.deleteByUserId(sysUser.getId());

             Arrays.stream(roles.split(",")).filter(StringUtils::isNotBlank)
                    .forEach(roleId -> {
                        SysUserRole sysUserRole = new SysUserRole();
                        sysUserRole.setUserId(sysUser.getId());
                        sysUserRole.setRoleId(Long.valueOf(roleId));
                        sysUserRoleRepository.save(sysUserRole);
                    });

        }
        return sysUser;
    }
}
